package com.mmall.util;

import java.io.IOException;
import java.text.SimpleDateFormat;
import java.util.List;

import org.apache.commons.lang3.StringUtils;
import org.codehaus.jackson.JsonGenerationException;
import org.codehaus.jackson.JsonParseException;
import org.codehaus.jackson.map.DeserializationConfig;
import org.codehaus.jackson.map.JsonMappingException;
import org.codehaus.jackson.map.ObjectMapper;
import org.codehaus.jackson.map.SerializationConfig;
import org.codehaus.jackson.map.annotate.JsonSerialize.Inclusion;
import org.codehaus.jackson.type.JavaType;
import org.codehaus.jackson.type.TypeReference;

import lombok.extern.slf4j.Slf4j;

import com.google.common.collect.Lists;
import com.mmall.pojo.*;

@Slf4j
public class JsonUtil {
	private static ObjectMapper objectMapper = new ObjectMapper();
	static {
		// 对象的所有字段全部列入
		objectMapper.setSerializationInclusion(Inclusion.ALWAYS);

		// 取消默认转换timestamps形式
		objectMapper.configure(SerializationConfig.Feature.WRITE_DATES_AS_TIMESTAMPS, false);

		// 忽略空Bean转json的错误
		objectMapper.configure(SerializationConfig.Feature.FAIL_ON_EMPTY_BEANS, false);

		// 所有的日期格式都统一为以下的样式，即yyyy-MM-dd HH:mm:ss
		objectMapper.setDateFormat(new SimpleDateFormat(DateTimeUtil.STANDARD_FORMAT));

		// 忽略 在json字符串中存在，但是在java对象中不存在对应属性的情况。防止错误
		objectMapper.configure(DeserializationConfig.Feature.FAIL_ON_UNKNOWN_PROPERTIES, false);
	}

	public static <T> String obj2String(T obj) {
		if (obj == null) {
			return null;
		}
		try {
			return obj instanceof String ? (String) obj : objectMapper.writeValueAsString(obj);
		} catch (Exception e) {
			log.warn("parse obj to string error",e);
			return null;
		}

	}
	public static <T> String obj2StringPretty(T obj) {
		if (obj == null) {
			return null;
		}
		try {
			return obj instanceof String ? (String) obj : objectMapper.writerWithDefaultPrettyPrinter().writeValueAsString(obj);
		} catch (Exception e) {
			log.warn("parse obj to string error",e);
			return null;
		}
		
	}
    public static <T> T string2Obj(String str,Class<T> clazz){//Class后面的T是限制class的类型，就行list里的string
        if(StringUtils.isEmpty(str) || clazz == null){
            return null;
        }

        try {
            return clazz.equals(String.class)? (T)str : objectMapper.readValue(str,clazz);
        } catch (Exception e) {
            log.warn("Parse String to Object error",e);
            return null;
        }
    }
    public static <T> T string2Obj(String str,TypeReference<T> typeReference){//Class后面的T是限制class的类型，就行list里的string
    	if(StringUtils.isEmpty(str) || typeReference == null){
    		return null;
    	}
    	
    	try {
    		return (T) (typeReference.getType().equals(String.class)? str : objectMapper.readValue(str,typeReference));
    	} catch (Exception e) {
    		log.warn("Parse String to Object error",e);
    		return null;
    	}
    }
    public static <T> T string2Obj2 (String str, Class<?> collectionclass, Class<?>... elementclass){
    	JavaType javaType = objectMapper.getTypeFactory().constructParametricType(collectionclass, elementclass);
    	try {
			return objectMapper.readValue(str, javaType);
		} catch ( Exception e) {
			log.warn("parse string to object error", e );
			return null;
		} 
    }

	public static void main(String[] args) {
    	User user = new User();
    	user.setAnswer("huida");
    	user.setEmail("youxiang");
    	String userJson = JsonUtil.obj2String(user);
    	String userJsonPretty = JsonUtil.obj2StringPretty(user);
    	log.info("hahja:{}" , userJson);
    	log.info("hahja:{}" , userJsonPretty);
    	User user2 = JsonUtil.string2Obj(userJson, User.class);
    	System.out.println("ok");

    	User user3 = new User();
    	user3.setAnswer("huida");
    	user3.setEmail("youxiang");
    	List<User> userlist = Lists.newArrayList();
    	userlist.add(user3);
    	userlist.add(user);
    	String userlistString = JsonUtil.obj2String(userlist);
    	String userlistString2 = JsonUtil.obj2StringPretty(userlist);

    	List<User> userlist2 = JsonUtil.string2Obj(userlistString, new TypeReference<List<User>>() {
		});
    	List<User> userlist3 = JsonUtil.string2Obj2(userlistString, List.class, User.class);
    	
    	System.out.println("ok");
    	
		
	}
	
}
